package com.yzc.android.ui.adapter;

import android.content.res.Resources.NotFoundException;
import android.support.annotation.LayoutRes;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

import com.marshalchen.ultimaterecyclerview.UltimateRecyclerviewViewHolder;
import com.marshalchen.ultimaterecyclerview.UltimateViewAdapter;
import com.yzc.android.ui.viewholder.KDBaseViewHolder;

/**
 * Created by yzc on 16/4/20.
 */
public abstract class KDRecyclerViewBaseAdapter<ItemDataType, ViewHolderType extends UltimateRecyclerviewViewHolder> extends UltimateViewAdapter {

    protected List<ItemDataType> mDataList;

    /**
     * dynamic object to start
     *
     * @param list the list source
     */
    public KDRecyclerViewBaseAdapter(List<ItemDataType> list) {
        mDataList = list;
    }


    /**
     * the layout id for the normal data
     *
     * @return the ID
     */
    protected abstract @LayoutRes int getItemLayoutResId();

    /**
     * the layout id for the normal data
     *
     * @return the ID
     */
    protected @LayoutRes int getSectionLayoutResId()
    {
        return -1;
    }

    /**
     * this is the Normal View Holder initiation
     *
     * @param view view
     * @return holder
     */
    protected abstract ViewHolderType createCustomViewHolder(View view, int viewTypes);

    /**
     * this is the Normal View Holder initiation
     *
     * @param
     * @return holder
     */
    protected abstract void bindCustomViewHolder(final KDBaseViewHolder holder, final int position, int viewTypes);


    @Override
    public ViewHolder newFooterHolder(final View view) {
        return createCustomViewHolder(view, VIEW_TYPES.FOOTER);
    }

    @Override
    public ViewHolder newHeaderHolder(final View view) {
        return createCustomViewHolder(view, VIEW_TYPES.HEADER);
    }

    @Override
    public ViewHolder onCreateViewHolder(final ViewGroup parent) {
        View view = LayoutInflater.from(parent.getContext()).inflate(getItemLayoutResId(), parent, false);
        return createCustomViewHolder(view, VIEW_TYPES.NORMAL);
    }

    @Override
    public int getAdapterItemCount() {
        return mDataList.size();
    }

    @Override
    public long generateHeaderId(final int position) {
        @LayoutRes int rId = getSectionLayoutResId();
        if (rId == -1)
        {
            throw new NotFoundException("method not overridden");
        }
        return -1;
    }

    @Override
    public ViewHolder onCreateHeaderViewHolder(final ViewGroup parent) {
        @LayoutRes int rId = getSectionLayoutResId();
        if (rId == -1)
        {
            return null;
        }
        View view = LayoutInflater.from(parent.getContext()).inflate(rId, parent, false);
        return createCustomViewHolder(view, VIEW_TYPES.SECTION);
    }

    @Override
    public void onBindHeaderViewHolder(final ViewHolder holder, final int position) {
        bindCustomViewHolder((KDBaseViewHolder) holder, hasHeaderView()?position-1:position, VIEW_TYPES.SECTION);
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        if (customHeaderView != null && position == 0)
        {
            bindCustomViewHolder((KDBaseViewHolder)holder, 0, VIEW_TYPES.HEADER);
        }
        else if (customHeaderView == null && position < getAdapterItemCount())
        {
            bindCustomViewHolder((KDBaseViewHolder)holder, position, VIEW_TYPES.NORMAL);
        }
        else if (customHeaderView != null && position > 0 && position <= getAdapterItemCount())
        {
            position -= 1;
            bindCustomViewHolder((KDBaseViewHolder)holder, position, VIEW_TYPES.NORMAL);
        }
    }

    public ItemDataType getItem(final int pos) {
        synchronized (mLock) {
            return mDataList.get(pos);
        }
    }

    /**
     * Determine if the object provide is in this adapter
     * @param  object the data object
     * @return true if the object is in this adapter
     */
    public boolean hasItem(ItemDataType object) {
        synchronized (mLock) {
            return mDataList.contains(object);
        }
    }

    /**
     * Returns whether this {@code List} contains no elements.
     *
     * @return {@code true} if this {@code List} has no elements, {@code false}
     * otherwise.
     * @see #mDataList
     */
    public boolean isEmpty() {
        return mDataList.size() == 0;
    }


    /**
     * @return a copy of the {@code List} of elements.
     */
    public List<ItemDataType> getObjects() {
        synchronized (mLock) {
            return new ArrayList<ItemDataType>(mDataList);
        }
    }

    public void insert(List<ItemDataType> new_data) {
        insertInternal(new_data, mDataList);
    }

    public void removeAll() {
        clearInternal(mDataList);
    }

    public void insertFirst(ItemDataType item) {
        insertFirstInternal(mDataList, item);
    }

    public void insertLast(ItemDataType item) {
        insertLastInternal(mDataList, item);
    }

    public final void removeAt(int pos) {
        removeInternal(mDataList, pos);
    }

    public void removeLast() {
        removeLastInternal(mDataList);
    }

    public void removeFirst() {
        removeFirstInternal(mDataList);
    }

    public final void swapPositions(int from, int to) {
        swapPositions(mDataList, from, to);
    }
}
